//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.example.wechat.login.service;

import cn.hutool.json.JSONUtil;
import com.example.wechat.login.dto.WechatLoginRequest;
import com.example.wechat.login.dto.WechatLoginResponse;
import com.example.wechat.login.dto.WechatSessionDTO;
import com.example.wechat.login.dto.WechatLoginResponse.UserInfo;
import com.example.wechat.login.entity.WechatUser;
import com.example.wechat.login.mapper.WechatUserMapper;
import com.example.wechat.login.util.HttpUtil;
import com.example.wechat.login.util.JwtUtil;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class WechatService {
    private static final Logger logger = LoggerFactory.getLogger(WechatService.class);
    @Value("${wechat.miniapp.appid}")
    private String appid;
    @Value("${wechat.miniapp.secret}")
    private String secret;
    @Value("${wechat.miniapp.code2session-url}")
    private String code2SessionUrl;
    private final HttpUtil httpUtil;
    private final JwtUtil jwtUtil;
    private final WechatUserMapper wechatUserMapper;

    public WechatService(HttpUtil httpUtil, JwtUtil jwtUtil, WechatUserMapper wechatUserMapper) {
        this.httpUtil = httpUtil;
        this.jwtUtil = jwtUtil;
        this.wechatUserMapper = wechatUserMapper;
    }

    public WechatSessionDTO getWechatSession(String code) {
        logger.info("获取微信会话信息，code: {}", code);
        Map<String, Object> params = new HashMap();
        params.put("appid", this.appid);
        params.put("secret", this.secret);
        params.put("js_code", code);
        params.put("grant_type", "authorization_code");
        String url = this.code2SessionUrl;
        String newUrl = String.format(url, code);
        logger.info("请求微信接口，url: {}, params: {}", newUrl, JSONUtil.toJsonStr(params));
        WechatSessionDTO sessionDTO = (WechatSessionDTO)this.httpUtil.get(newUrl, params, WechatSessionDTO.class);
        if (sessionDTO.getErrcode() != null && sessionDTO.getErrcode() != 0) {
            logger.error("获取微信会话信息失败，错误码: {}, 错误信息: {}", sessionDTO.getErrcode(), sessionDTO.getErrmsg());
            throw new RuntimeException("获取微信会话信息失败: " + sessionDTO.getErrmsg());
        } else {
            logger.info("获取微信会话信息成功，openid: {}", sessionDTO.getOpenid());
            return sessionDTO;
        }
    }

    @Transactional
    public WechatLoginResponse login(WechatLoginRequest loginRequest) {
        logger.info("处理微信用户登录，code: {}", loginRequest.getCode());
        WechatSessionDTO sessionDTO = this.getWechatSession(loginRequest.getCode());
        String openid = sessionDTO.getOpenid();
        String sessionKey = sessionDTO.getSessionKey();
        String unionid = sessionDTO.getUnionid();
        WechatUser user = this.findOrCreateUser(openid, unionid, sessionKey, loginRequest);
        String token = this.jwtUtil.generateToken(openid);
        WechatLoginResponse response = WechatLoginResponse.builder().token(token).userInfo(UserInfo.fromEntity(user)).build();
        logger.info("微信用户登录成功，openid: {}", openid);
        return response;
    }

    private WechatUser findOrCreateUser(String openid, String unionid, String sessionKey, WechatLoginRequest loginRequest) {
        Optional<WechatUser> optionalUser = Optional.ofNullable(this.wechatUserMapper.findByOpenid(openid));
        if (optionalUser.isPresent()) {
            WechatUser existingUser = (WechatUser)optionalUser.get();
            this.updateUserInfo(existingUser, unionid, sessionKey, loginRequest);
            return (WechatUser)this.wechatUserMapper.findByOpenid(existingUser.getOpenid());
        } else {
            WechatUser newUser = new WechatUser();
            newUser.setOpenid(openid);
            this.insertUserInfo(newUser, unionid, sessionKey, loginRequest);
            return (WechatUser)this.wechatUserMapper.findByOpenid(newUser.getOpenid());
        }
    }

    private void updateUserInfo(WechatUser user, String unionid, String sessionKey, WechatLoginRequest loginRequest) {
        user.setUnionid(unionid);
        user.setSessionKey(sessionKey);
        user.setLastLoginTime(LocalDateTime.now());
        if (loginRequest.getUserInfo() != null) {
            WechatLoginRequest.UserInfo userInfo = loginRequest.getUserInfo();
            user.setNickname(userInfo.getNickName());
            user.setAvatarUrl(userInfo.getAvatarUrl());
            user.setGender(userInfo.getGender());
            user.setCountry(userInfo.getCountry());
            user.setProvince(userInfo.getProvince());
            user.setCity(userInfo.getCity());
            user.setLanguage(userInfo.getLanguage());
            wechatUserMapper.updateById( user);
        }

    }


    private void insertUserInfo(WechatUser user, String unionid, String sessionKey, WechatLoginRequest loginRequest) {
        user.setUnionid(unionid);
        user.setSessionKey(sessionKey);
        user.setLastLoginTime(LocalDateTime.now());
        if (loginRequest.getUserInfo() != null) {
            WechatLoginRequest.UserInfo userInfo = loginRequest.getUserInfo();
            user.setNickname(userInfo.getNickName());
            user.setAvatarUrl(userInfo.getAvatarUrl());
            user.setGender(userInfo.getGender());
            user.setCountry(userInfo.getCountry());
            user.setProvince(userInfo.getProvince());
            user.setCity(userInfo.getCity());
            user.setLanguage(userInfo.getLanguage());
            wechatUserMapper.insert( user);
        }

    }
}
